using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using JGSY.CMS.LowCode.Platform.Application.Interfaces;
using JGSY.CMS.LowCode.Platform.Application.DTOs;
using JGSY.CMS.LowCode.Platform.Domain.Interfaces;
using JGSY.CMS.LowCode.Platform.Domain.Entities;

namespace JGSY.CMS.LowCode.Platform.Application.Services
{
    /// <summary>
    /// 配置管理服务。
    /// 提供系统配置的获取、设置、刷新和分组管理等功能，支持缓存机制提高性能。
    /// </summary>
    [JGSY.CMS.LowCode.Platform.Infrastructure.Services.LogOperation]
    public class ConfigService : IConfigService
    {
        /// <summary>
        /// 系统设置仓储接口
        /// </summary>
        private readonly ISystemSettingRepository _repository;
        
        /// <summary>
        /// 配置缓存字典
        /// </summary>
        private IDictionary<string, string> _cache = new Dictionary<string, string>();
        
        /// <summary>
        /// 构造函数，注入系统设置仓储
        /// </summary>
        /// <param name="repository">系统设置仓储接口</param>
        public ConfigService(ISystemSettingRepository repository)
        {
            _repository = repository;
        }
        
        /// <summary>
        /// 根据键获取配置值，优先从缓存获取
        /// </summary>
        /// <param name="key">配置键</param>
        /// <returns>配置值</returns>
        public async Task<string?> GetValueAsync(string key)
        {
            if (_cache.TryGetValue(key, out var value)) return value;
            var all = await _repository.GetAllAsync();
            var setting = all.FirstOrDefault(s => s.Key == key);
            if (setting != null && setting.IsEnabled)
            {
                _cache[key] = setting.Value;
                return setting.Value;
            }
            // 未启用则返回 appsettings.json 默认值
            // 可扩展：读取 IConfiguration
            return null;
        }
        
        /// <summary>
        /// 根据类别获取配置组
        /// </summary>
        /// <param name="category">配置类别</param>
        /// <returns>指定类别的配置键值对字典</returns>
        public async Task<IDictionary<string, string>> GetGroupAsync(string category)
        {
            var list = await _repository.GetByCategoryAsync(category);
            return list.ToDictionary(s => s.Key, s => s.Value);
        }
        
        /// <summary>
        /// 设置配置值并更新缓存
        /// </summary>
        /// <param name="key">配置键</param>
        /// <param name="value">配置值</param>
        /// <param name="category">配置类别，默认为空</param>
        /// <param name="description">配置描述，默认为空</param>
        /// <param name="isEnabled">是否启用，默认为true</param>
        /// <returns>设置任务</returns>
        public async Task SetValueAsync(string key, string value, string category = "", string description = "", bool isEnabled = true)
        {
            // 禁止删除参数，只允许新增或修改
            var all = await _repository.GetAllAsync();
            var setting = all.FirstOrDefault(s => s.Key == key);
            if (setting == null)
            {
                // 仅允许新增 Key，不能删除
                await _repository.AddAsync(new SystemSetting
                {
                    //Id =long.Newlong(),
                    Key = key,
                    Value = value,
                    Category = category,
                    Description = description,
                    IsEnabled = isEnabled
                });
            }
            else
            {
                // 仅允许修改 Value、IsEnabled、Category、Description
                setting.Value = value;
                setting.Category = category;
                setting.Description = description;
                setting.IsEnabled = isEnabled;
                await _repository.UpdateAsync(setting);
            }
            _cache[key] = value;
        }
        
        /// <summary>
        /// 刷新配置缓存，重新从数据库加载所有配置
        /// </summary>
        /// <returns>刷新任务</returns>
        public async Task RefreshAsync()
        {
            var all = await _repository.GetAllAsync();
            _cache = all.ToDictionary(s => s.Key, s => s.Value);
        }
        
        /// <summary>
        /// 获取所有系统设置
        /// </summary>
        /// <returns>系统设置列表</returns>
        public async Task<IEnumerable<SystemSettingDto>> GetAllAsync()
        {
            var all = await _repository.GetAllAsync();
            return all.Select(s => new SystemSettingDto
            {
                Id = s.Id,
                Key = s.Key,
                Value = s.Value,
                Category = s.Category,
                Description = s.Description
            });
        }
    }
}
